#pragma once

#include<string>
#include<vector>
#include<fstream>
#include<sstream>
#include<iostream>

using namespace std;

#define Z_ATOMIC 0
#define Z_DOUHAO 1
#define Z_RET 2
#define Z_THREEYE 3
#define Z_GIVER 4
#define Z_LOGIC 5
#define Z_ADD_MATH 6
#define Z_MUL_MATH 7
#define Z_BIT_MATH 8
#define Z_ONEYE 9
#define Z_MEMGETER 10
#define Z_PandCALL 11
#define Z_ALPHT 12
#define Z_GJZ 13 

short prio(const string&str){
	if(str=="+"||str=="-"){
		return Z_ADD_MATH;
	}
	if(str[0]=='+'||str[0]=='-'||str[0]=='\''||str[0]=='\"'||(str[0]>='0'&&str[0]<='9')){
		return Z_ATOMIC;
	}
	if(str[0]=='('||str[0]==')'||str[0]=='{'||str[0]=='}'){
		return Z_PandCALL;
	}
	if(str[0]=='.'||str[0]=='['||str[0]==']'){
		return Z_MEMGETER;
	}
	if(str=="let"||str=="mut"||str=="func"||str=="print"||str=="in"
		||str=="lock"||str=="typeof"||str=="if"||str=="exec"||str=="slice"||str=="exit")
		return Z_GJZ;
	if(str=="*"||str=="/"||str=="%")
		return Z_MUL_MATH;
	return Z_ALPHT;
}
struct token{
	string str;
	short wv;
	// 保留原构造函数逻辑
	token() : wv(0) {}
	token(const string &s) : str(s), wv(prio(s)) {}
};

class Words{
	public:
		vector<vector<token>> words;
		Words(){}
		Words(const string &str){
			load(str);
		}
		void load(const string &str){
			ifstream ifp(str);
			if(!ifp.is_open()){
				cerr<<"Error: Cannot open file "<<str<<endl;
				return;
			}
			string t;
			while(getline(ifp,t)){
				if(t.empty()) continue;
				if(t[0]=='$'){
					string sub_file = t.substr(1);
					load(sub_file);
					continue;
				}
				lexer(t);
			}
		}
		static char chcl(const char &a){
			if((a>='a'&&a<='z')||(a>='A'&&a<='Z')||(a>='0'&&a<='9')||a=='_'||a=='.'){
				return 'a';
			}
			if(a=='('||a==')'||a=='['||a==']'||a=='{'||a=='}'||a=='/'||a=='\"'||a==','){
				return a;
			}
			return 'o';
		}
		void lexer(const string &str){
			vector<token> wordss;
			char flag = 0;  // 0:未开始  'a':字母数字  '(':括号类  '"':字符串内  'o':普通符号
			string s;
			// 新增：标记是否处于字符串内部（解决引号内字符类型不中断的核心逻辑）
			bool in_string = false;

			for(auto &a:str){
				// 1. 处理空格：仅在非字符串内部时，空格分隔token
				if(a==' ' && !in_string){
					if(!s.empty()){
						wordss.push_back(token(s));
						s.clear();
					}
					flag = 0;
					continue;
				}

				// 2. 处理字符串引号：切换字符串内部状态
				if(a=='"'){
					if(!s.empty()&&!in_string){
						wordss.push_back(token(s));
						s.clear();
					}
					s += a;  // 把引号加入当前token
					in_string = !in_string;  // 进入/退出字符串模式
					flag = '"';  // 标记当前token为字符串类型
					// 若退出字符串（第二个引号），直接保存该字符串token
					if(!in_string){
						wordss.push_back(token(s));
						s.clear();
						flag = 0;
					}
					continue;
				}

				// 3. 字符串内部逻辑：忽略字符类型差异，全部拼接到当前token
				if(in_string){
					s += a;
					continue;
				}

				// 4. 非字符串区域：按原字符类型逻辑处理
				if(flag){
					if((flag != chcl(a))||flag==')'||flag=='('||flag=='['||flag==']'){
						wordss.push_back(token(s));
						s = string(1,a);
						flag = chcl(a);
					}else{
						s += string(1,a);
					}
				}else{
					s += string(1,a);
					flag = chcl(a);
				}
			}

			// 5. 处理行尾残留token（非字符串状态下）
			if(!s.empty() && !in_string){
				wordss.push_back(token(s));
			}
			// 6. 若行尾仍在字符串内（未闭合引号），也保存当前内容
			else if(!s.empty() && in_string){
				cerr<<"Warning: Unclosed string at line end: "<<s<<endl;
				wordss.push_back(token(s));
			}

			words.push_back(wordss);
		}
};//lexer.hpp